#include <Root.hpp>

Modeling::Root::~Root()
{
	std::map<std::string, Modeling::Material*>::iterator matIt;
	for (matIt = this->material.begin() ; matIt != this->material.end() ; matIt++ ) {
		delete matIt->second;
	}
	this->material.clear();

	std::map<std::string, Modeling::Node*>::iterator nodeIt;
	for (nodeIt = this->node.begin() ; nodeIt != this->node.end() ; nodeIt++ ) {
		delete nodeIt->second;
	}
	this->node.clear();
}

Modeling::Root::Root()
{}

Modeling::Root::Root(std::string name)
{}

int Modeling::Root::type()
{
	return Modeling::ROOT;
}

void Modeling::Root::animate(unsigned int frame)
{}

Modeling::Node* Modeling::Root::getNode(std::string name)
{
	return this->node[name];
}

void Modeling::Root::addNode(std::string parent, Modeling::Node* node)
{	
	if (parent == this->getName()) {
		this->addChild(node);
	} else {
		this->getNode(parent)->addChild(node);
	}

	this->node[node->getName()] = node;
}

unsigned int Modeling::Root::getNodesQty()
{
	return this->node.size();
}

Modeling::Mesh* Modeling::Root::addMesh(std::string parent, std::string name)
{
	Modeling::Mesh* mesh = new Modeling::Mesh(name);
	this->addNode(parent, mesh);
	return mesh;
}

Modeling::Camera* Modeling::Root::addCamera(std::string parent, std::string name)
{
	Modeling::Camera* camera = new Modeling::Camera(name);
	this->addNode(parent, camera);
	return camera;
}

Modeling::Light* Modeling::Root::addLight(std::string parent, std::string name)
{
	Modeling::Light* light = new Modeling::Light(name);
	this->addNode(parent, light);
	return light;
}

Modeling::Material* Modeling::Root::getMaterial(std::string name)
{
	return this->material[name];
}

Modeling::Material* Modeling::Root::addMaterial(std::string name)
{
	// If a material identified by 'name' is not already in the map ...
	if (this->material.find(name) == this->material.end()) {
		// ... add a new material identified by 'name'
		this->material[name] = new Modeling::Material(name);
	}
	// return the material found or the new one.
	return this->material[name];
}

unsigned int Modeling::Root::getMaterialsQty()
{
	return this->material.size();
}

std::map< std::string, Modeling::Material* >* Modeling::Root::getMaterialMap()
{
	return &this->material;
}
